home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / dpmigcc5.zip / RSX / SOURCE / FPU-EMU / FPU_ETC.C < prev    next >
C/C++ Source or Header  |  1994-05-27  |  3KB  |  128 lines

  1. /*---------------------------------------------------------------------------+
  2.  |  fpu_etc.c                                                                |
  3.  |                                                                           |
  4.  | Implement a few FPU instructions.                                         |
  5.  |                                                                           |
  6.  | Copyright (C) 1992,1993,1994                                              |
  7.  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  8.  |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
  9.  |                                                                           |
  10.  |                                                                           |
  11.  +---------------------------------------------------------------------------*/
  12.  
  13. #include "fpu_system.h"
  14. #include "exception.h"
  15. #include "fpu_emu.h"
  16. #include "status_w.h"
  17. #include "reg_constant.h"
  18.  
  19.  
  20. static void fchs(void)
  21. {
  22.   if ( NOT_EMPTY_0 )
  23.     {
  24.       FPU_st0_ptr->sign ^= SIGN_POS^SIGN_NEG;
  25.       clear_C1();
  26.     }
  27.   else
  28.     stack_underflow();
  29. }
  30.  
  31. static void fabs(void)
  32. {
  33.   if ( FPU_st0_tag ^ TW_Empty )
  34.     {
  35.       FPU_st0_ptr->sign = SIGN_POS;
  36.       clear_C1();
  37.     }
  38.   else
  39.     stack_underflow();
  40. }
  41.  
  42.  
  43. static void ftst_(void)
  44. {
  45.   switch (FPU_st0_tag)
  46.     {
  47.     case TW_Zero:
  48.       setcc(SW_C3);
  49.       break;
  50.     case TW_Valid:
  51.       if (FPU_st0_ptr->sign == SIGN_POS)
  52.         setcc(0);
  53.       else
  54.         setcc(SW_C0);
  55.  
  56. #ifdef DENORM_OPERAND
  57.       if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )
  58.     {
  59. #ifdef PECULIAR_486
  60.       /* This is wierd! */
  61.       if (FPU_st0_ptr->sign == SIGN_POS)
  62.         setcc(SW_C3);
  63. #endif PECULIAR_486
  64.       return;
  65.     }
  66. #endif DENORM_OPERAND
  67.  
  68.       break;
  69.     case TW_NaN:
  70.       setcc(SW_C0|SW_C2|SW_C3);   /* Operand is not comparable */ 
  71.       EXCEPTION(EX_Invalid);
  72.       break;
  73.     case TW_Infinity:
  74.       if (FPU_st0_ptr->sign == SIGN_POS)
  75.         setcc(0);
  76.       else
  77.         setcc(SW_C0);
  78.       break;
  79.     case TW_Empty:
  80.       setcc(SW_C0|SW_C2|SW_C3);
  81.       EXCEPTION(EX_StackUnder);
  82.       break;
  83.     default:
  84.       setcc(SW_C0|SW_C2|SW_C3);   /* Operand is not comparable */ 
  85.       EXCEPTION(EX_INTERNAL|0x14);
  86.       break;
  87.     }
  88. }
  89.  
  90. static void fxam(void)
  91. {
  92.   int c=0;
  93.   switch (FPU_st0_tag)
  94.     {
  95.     case TW_Empty:
  96.       c = SW_C3|SW_C0;
  97.       break;
  98.     case TW_Zero:
  99.       c = SW_C3;
  100.       break;
  101.     case TW_Valid:
  102.       /* This will need to be changed if TW_Denormal is ever used. */
  103.       if ( FPU_st0_ptr->exp <= EXP_UNDER )
  104.         c = SW_C2|SW_C3;  /* Denormal */
  105.       else
  106.         c = SW_C2;
  107.       break;
  108.     case TW_NaN:
  109.       c = SW_C0;
  110.       break;
  111.     case TW_Infinity:
  112.       c = SW_C2|SW_C0;
  113.       break;
  114.     }
  115.   if (FPU_st0_ptr->sign == SIGN_NEG)
  116.     c |= SW_C1;
  117.   setcc(c);
  118. }
  119.  
  120. static FUNC const fp_etc_table[] = {
  121.   fchs, fabs, FPU_illegal, FPU_illegal, ftst_, fxam, FPU_illegal, FPU_illegal
  122. };
  123.  
  124. void fp_etc()
  125. {
  126.   (fp_etc_table[FPU_rm])();
  127. }
  128.